#include "animationsystem.h"
#include <fstream>
using std::ifstream;

void Model::LoadMeshesFromFile(std::string fileName)
{
	// We won't actually be loading anything for this example,
	// so we'll just procedurally generate a cylinder mesh to use

	const unsigned int uiSegmentCount = 5;
	const float fSegmentLength = 2.0f;
	const unsigned int uiRes = 10;
	const float fRadius = 1.0f;

	// Just the one mesh
	m_vMeshes.resize(1);

	m_vMeshes[0].m_vWeights.resize(uiRes*uiSegmentCount);

	#define EDPI 3.1415926535897932384626433832795f

	for( unsigned int j = 0; j < uiSegmentCount; ++j )
	{
		for( float i = 0.0f; i < 2.0f*EDPI; i += (2.0f*EDPI) / uiRes )
			m_vMeshes[0].GetVertices().push_back( vec3f( (float)j*fSegmentLength, cos(i) * fRadius, sin(i) * fRadius ) );

		unsigned int uiLTIndex = j * uiRes;

		if( j < uiSegmentCount - 1 )
			for( unsigned int i = 0; i < uiRes; ++i )
			{
				m_vMeshes[0].GetIndices().push_back( uiLTIndex + i );
				i + 1 == uiRes ? m_vMeshes[0].GetIndices().push_back( uiLTIndex ) : m_vMeshes[0].GetIndices().push_back( uiLTIndex + i + 1 );
				m_vMeshes[0].GetIndices().push_back( uiLTIndex + i + uiRes );

				m_vMeshes[0].GetIndices().push_back( uiLTIndex + i + uiRes );
				i + 1 == uiRes ? m_vMeshes[0].GetIndices().push_back( uiLTIndex ) : m_vMeshes[0].GetIndices().push_back( uiLTIndex + i + 1 );
				i + 1 == uiRes ? m_vMeshes[0].GetIndices().push_back( uiLTIndex + uiRes ) : m_vMeshes[0].GetIndices().push_back( uiLTIndex + i + 1 + uiRes );
			}

		for( unsigned int i = 0; i < uiRes; ++i )
		{
			float fWeight = (float)j / (float)(uiSegmentCount-1);
			float fInvWeight = 1.0f - fWeight;

			m_vMeshes[0].m_vWeights[j*uiRes+i].push_back( fInvWeight );
			m_vMeshes[0].m_vWeights[j*uiRes+i].push_back( fWeight );

			//Weights[j*uiRes+i][0] = fInvWeight;
			//Weights[j*uiRes+i][1] = fWeight;
		}
	}
}

////////////////////////////////////////////////////////////////
// Loads the animation from a file
//
// Parameters
// string fileName - the name of the animation file
////////////////////////////////////////////////////////////////
void Animation::LoadFromFile(std::string fileName)
{
	// We'll be doing a prodedural animation in the interpolator for this example, so the only "animation" data
	// we will have will be our bind pose

	m_vKeyFrames.resize(1);
	m_vKeyFrames[0].m_fKeyTime = 0.0f;
	m_vKeyFrames[0].m_vTransformFrames.resize(2);

	m_vKeyFrames[0].m_vTransformFrames[0].GetLocalMat().make_identity();
	m_vKeyFrames[0].m_vTransformFrames[0].Update();
	m_vKeyFrames[0].m_vTransformFrames[1].GetLocalMat().make_identity();
	m_vKeyFrames[0].m_vTransformFrames[1].GetLocalMat().axis_pos.x = 4.0f;
	m_vKeyFrames[0].m_vTransformFrames[1].Update();
	m_vKeyFrames[0].m_vTransformFrames[0].AddChild( &m_vKeyFrames[0].m_vTransformFrames[1] );
}

////////////////////////////////////////////////////////////////
// Attaches an animation to the interpolator
//
// Parameters
// const Animation *inAnimation - the animation to attach to
////////////////////////////////////////////////////////////////
void Interpolator::SetAnimation(const Animation *inAnimation)
{
	m_pAnimation = inAnimation;
	SetTime(0.0f);

	// Initial values same as our bind pose for procedural animation...
	m_CurrentKeyFrame.m_fKeyTime = 0.0f;
	m_CurrentKeyFrame.m_vTransformFrames.resize(2);

	m_CurrentKeyFrame.m_vTransformFrames[0].GetLocalMat().make_identity();
	m_CurrentKeyFrame.m_vTransformFrames[0].Update();
	m_CurrentKeyFrame.m_vTransformFrames[1].GetLocalMat().make_identity();
	m_CurrentKeyFrame.m_vTransformFrames[1].GetLocalMat().axis_pos.x = 4.0f;
	m_CurrentKeyFrame.m_vTransformFrames[1].Update();
	m_CurrentKeyFrame.m_vTransformFrames[0].AddChild( &m_CurrentKeyFrame.m_vTransformFrames[1] );
}

////////////////////////////////////////////////////////////////
// Interpolates between the animations key-frames based on the 
// interolator's current time
////////////////////////////////////////////////////////////////
void Interpolator::Process(void)
{
	// Some simple procedural animation...
	m_fAngleTot += m_fAngle;

	if( m_fAngleTot >= 1.0f || m_fAngleTot <= -1.0f )
		m_fAngle = -m_fAngle;

	m_CurrentKeyFrame.m_vTransformFrames[0].GetLocalMat().rotate_z_pre( m_fAngle );
	m_CurrentKeyFrame.m_vTransformFrames[0].Update();
	m_CurrentKeyFrame.m_vTransformFrames[1].GetLocalMat().rotate_z_pre( -m_fAngle*2.0f );
	m_CurrentKeyFrame.m_vTransformFrames[1].Update();
}
